package miniop

import (
	"cloudstation/util"
	"fmt"
	"log"
	"net/url"
	"os"
	"time"

	"github.com/minio/minio-go/v6"
)

var (
	location    = "cn-north-1"
	contentType = "application/octet-stream"
)

type minIo struct {
	Endpoint  string `validate:"required"`
	AccessID  string `validate:"required"`
	AccessKey string `validate:"required"`
	UseSSL    bool
	// listner   oss.ProgressListener
}

// NewAliyun: 构建函数
func NewUploader(endpoint, accessID, accessKey string) (*minIo, error) {
	Mini := &minIo{
		Endpoint:  endpoint,
		AccessID:  accessID,
		AccessKey: accessKey,
		UseSSL:    false,
	}

	if err := util.Validate(Mini); err != nil {
		return nil, err
	}
	return Mini, nil
}

func (m *minIo) UploadFile(bucketName, objectKey, localFilePath string) error {

	mini, err := NewUploader(m.Endpoint, m.AccessID, m.AccessKey)
	if err != nil {
		return err
	}

	minioClient, err := mini.getClient(bucketName, location)
	if err != nil {
		return err
	}

	_, err = minioClient.FPutObject(bucketName, objectKey, localFilePath, minio.PutObjectOptions{ContentType: contentType, Progress: os.Stdout})
	if err != nil {
		log.Fatalln(err)
	}
	reqParams := make(url.Values)

	signedURL, err := minioClient.PresignedGetObject(bucketName, objectKey, time.Second*24*60*60, reqParams)
	if err != nil {
		return fmt.Errorf("SignURL error, %s", err)
	}
	fmt.Printf("下载链接: %s\n", signedURL.String())
	fmt.Println("\n注意: 文件下载有效期为1天, 中转站保存时间为3天, 请及时下载")

	return err
}

// getClient： 获取getClient
func (m *minIo) getClient(bucketName, location string) (*minio.Client, error) {
	if bucketName == "" {
		return nil, fmt.Errorf("upload bucket name required")
	}
	// 初使化 minio client对象。
	minioClient, err := minio.New(m.Endpoint, m.AccessID, m.AccessKey, m.UseSSL)
	if err != nil {
		log.Fatalln(err)
	}
	// 创建一个叫mymusic的存储桶。
	err = minioClient.MakeBucket(bucketName, location)
	if err != nil {
		// 检查存储桶是否已经存在。
		exists, err := minioClient.BucketExists(bucketName)
		if err == nil && exists {
			log.Printf("We already own %s\n", bucketName)
		} else {
			return nil, err
		}
	}
	return minioClient, nil

}
